// React相关导入
import React, { useState, useRef, useEffect, useCallback } from 'react';
// 组件样式文件
import './index.css';

/**
 * 滑动验证组件属性接口
 */
interface SliderCaptchaProps {
  visible: boolean;        // 是否显示验证组件
  onClose: () => void;     // 关闭验证回调
  onSuccess: () => void;   // 验证成功回调
  onFail: () => void;      // 验证失败回调
  imageUrl?: string;       // 验证图片URL（可选）
}

/**
 * 拼图块位置信息接口
 */
interface PuzzlePiece {
  x: number;      // X坐标
  y: number;      // Y坐标
  width: number;  // 宽度
  height: number; // 高度
}

/**
 * 滑动验证组件
 * 提供拼图滑动验证功能，用户需要将拼图块拖拽到正确位置
 */
const SliderCaptcha: React.FC<SliderCaptchaProps> = ({
  visible,
  onClose,
  onSuccess,
  onFail,
  imageUrl = '/src/assets/captcha-bg.svg' // 默认验证图片
}) => {
  // 状态管理
  const [isDragging, setIsDragging] = useState(false); // 是否正在拖拽
  const [sliderPosition, setSliderPosition] = useState(0); // 滑块当前位置
  const [puzzlePiece, setPuzzlePiece] = useState<PuzzlePiece>({ x: 0, y: 0, width: 40, height: 40 }); // 拼图块信息
  const [targetPosition, setTargetPosition] = useState(0); // 目标位置
  const [isVerified, setIsVerified] = useState(false); // 是否已验证
  const [verificationResult, setVerificationResult] = useState<'success' | 'fail' | null>(null); // 验证结果
  const [showResult, setShowResult] = useState(false); // 是否显示结果提示

  // DOM引用
  const sliderRef = useRef<HTMLDivElement>(null); // 滑块元素引用
  const containerRef = useRef<HTMLDivElement>(null); // 容器元素引用
  const startXRef = useRef(0); // 拖拽开始时的X坐标
  const sliderStartXRef = useRef(0); // 拖拽开始时滑块位置

  /**
   * 初始化验证组件
   * 当组件显示时生成随机的目标位置和拼图块
   */
  useEffect(() => {
    if (visible) {
      const maxX = 280; // 最大可移动距离
      const randomX = Math.random() * maxX; // 生成随机目标位置
      setTargetPosition(randomX);
      setPuzzlePiece({
        x: randomX,
        y: Math.random() * 160, // 随机Y位置
        width: 40,
        height: 40
      });
      setSliderPosition(0); // 重置滑块位置
      setIsVerified(false); // 重置验证状态
      setVerificationResult(null); // 重置验证结果
      setShowResult(false); // 隐藏结果提示
    }
  }, [visible]);

  /**
   * 鼠标按下事件处理
   * 开始拖拽操作
   */
  const handleMouseDown = useCallback((e: React.MouseEvent) => {
    if (isVerified) return; // 已验证时不允许拖拽
    
    setIsDragging(true); // 设置拖拽状态
    startXRef.current = e.clientX; // 记录起始鼠标位置
    sliderStartXRef.current = sliderPosition; // 记录起始滑块位置
    
    // 添加全局事件监听
    document.addEventListener('mousemove', handleMouseMove);
    document.addEventListener('mouseup', handleMouseUp);
  }, [sliderPosition, isVerified]);

  /**
   * 鼠标移动事件处理
   * 更新滑块位置
   */
  const handleMouseMove = useCallback((e: MouseEvent) => {
    if (!isDragging) return; // 未在拖拽状态时忽略
    
    const deltaX = e.clientX - startXRef.current; // 计算鼠标移动距离
    const newPosition = Math.max(0, Math.min(280, sliderStartXRef.current + deltaX)); // 限制滑块范围
    setSliderPosition(newPosition); // 更新滑块位置
  }, [isDragging]);

  /**
   * 鼠标释放事件处理
   * 结束拖拽并进行验证
   */
  const handleMouseUp = useCallback(() => {
    if (!isDragging) return; // 未在拖拽状态时忽略
    
    setIsDragging(false); // 设置拖拽状态为false
    // 移除全局事件监听
    document.removeEventListener('mousemove', handleMouseMove);
    document.removeEventListener('mouseup', handleMouseUp);
    
    // 验证位置是否正确
    const tolerance = 10; // 容错范围（像素）
    const isCorrect = Math.abs(sliderPosition - targetPosition) <= tolerance; // 判断是否在容错范围内
    
    if (isCorrect) {
      // 验证成功
      setVerificationResult('success');
      setIsVerified(true);
      setShowResult(true);
      setTimeout(() => {
        onSuccess(); // 调用成功回调
        onClose();   // 关闭验证组件
      }, 1000);
    } else {
      // 验证失败
      setVerificationResult('fail');
      setShowResult(true);
      setTimeout(() => {
        setShowResult(false);
        setSliderPosition(0); // 重置滑块位置
        setVerificationResult(null);
      }, 1000);
      onFail(); // 调用失败回调
    }
  }, [isDragging, sliderPosition, targetPosition, onSuccess, onFail, onClose]);

  /**
   * 刷新验证
   * 重新生成目标位置和拼图块
   */
  const handleRefresh = () => {
    const maxX = 280;
    const randomX = Math.random() * maxX; // 生成新的随机目标位置
    setTargetPosition(randomX);
    setPuzzlePiece({
      x: randomX,
      y: Math.random() * 160, // 随机Y位置
      width: 40,
      height: 40
    });
    setSliderPosition(0); // 重置滑块位置
    setIsVerified(false); // 重置验证状态
    setVerificationResult(null); // 重置验证结果
    setShowResult(false); // 隐藏结果提示
  };

  // 如果不可见则返回null
  if (!visible) return null;

  return (
    <div className="slider-captcha-overlay">
      <div className="slider-captcha-modal">
        {/* 组件头部 - 标题和操作按钮 */}
        <div className="slider-captcha-header">
          <span className="slider-captcha-title">请完成下列验证后继续</span>
          <div className="slider-captcha-actions">
            {/* 刷新按钮 */}
            <button 
              className="slider-captcha-refresh" 
              onClick={handleRefresh}
              title="刷新"
            >
              🔄
            </button>
            {/* 关闭按钮 */}
            <button 
              className="slider-captcha-close" 
              onClick={onClose}
              title="关闭"
            >
              ✕
            </button>
          </div>
        </div>

        {/* 图片验证区域 */}
        <div className="slider-captcha-image-container" ref={containerRef}>
          <div 
            className="slider-captcha-image"
            style={{ backgroundImage: `url(${imageUrl})` }}
          >
            {/* 目标位置 - 虚线框指示用户需要拖拽到的位置 */}
            <div 
              className="slider-captcha-target"
              style={{
                left: `${targetPosition}px`,
                top: `${puzzlePiece.y}px`,
                width: `${puzzlePiece.width}px`,
                height: `${puzzlePiece.height}px`
              }}
            />
            
            {/* 拼图块 - 可拖拽的元素 */}
            <div 
              className="slider-captcha-puzzle-piece"
              style={{
                left: `${sliderPosition}px`,
                top: `${puzzlePiece.y}px`,
                width: `${puzzlePiece.width}px`,
                height: `${puzzlePiece.height}px`,
                backgroundImage: `url(${imageUrl})`,
                backgroundPosition: `-${targetPosition}px -${puzzlePiece.y}px` // 显示拼图块对应的图片部分
              }}
            />
          </div>
        </div>

        {/* 滑块拖拽区域 */}
        <div className="slider-captcha-slider-container">
          <div className="slider-captcha-track">
            {/* 滑块 - 可拖拽的滑块元素 */}
            <div 
              ref={sliderRef}
              className={`slider-captcha-slider ${isDragging ? 'dragging' : ''}`}
              style={{ left: `${sliderPosition}px` }}
              onMouseDown={handleMouseDown} // 绑定鼠标按下事件
            >
              <span className="slider-captcha-arrow">→</span>
            </div>
          </div>
          {/* 操作说明 */}
          <div className="slider-captcha-instruction">
            按住左边按钮移动完成上方拼图
          </div>
        </div>

        {/* 验证结果提示 */}
        {showResult && (
          <div className={`slider-captcha-result ${verificationResult}`}>
            {verificationResult === 'success' ? '验证成功！' : '验证失败，请重试'}
          </div>
        )}

        {/* 组件水印 */}
        <div className="slider-captcha-watermark">
          CSDN @LuviaWu
        </div>
      </div>
    </div>
  );
};

// 导出滑动验证组件
export default SliderCaptcha; 